<?php

namespace App\Service\Message\v1_0_4;

use App\Constants\AccostBusinesswomen;
use App\Constants\ErrorCode;
use App\Model\AccostLog;
use App\Model\User;
use App\Model\UserAutoMsg;
use App\Model\UserChat;
use App\Service\BaseService;
use App\Service\ServiceTrait\AccostTrait;
use App\Service\ServiceTrait\GetUserInfoTrait;
use Hyperf\DbConnection\Db;
use Hyperf\Redis\Redis;
use RedisException;

//use function GuzzleHttp\json_encode;

/**
 * 一键搭讪 - 打招呼
 */
class ChatQuickService extends BaseService
{
    use AccostTrait, GetUserInfoTrait;

    const ERROR_CODE = 0;

    /**
     * @var int
     */
    private $actionUserId;

    /**
     * @var Redis|mixed
     */
    private $redis;

    /**
     * 用户的key
     * @var string
     */
    private $key;

    /**
     * 锁定的用户key
     * @var string
     */
    private $lockKey;

    /**
     * 用户打招呼的key
     * @var string
     */
    private $numKey;

    /**
     * 执行搭讪
     * @return array
     * @throws RedisException
     */
    public function handle(): array
    {
        $ret = [];

        $this->actionUserId = $this->getUserId();

        $isNewVersion = $this->request->input('version', '1.0') >= '1.0.0';
        $chatUserIds = $this->request->input('chat_userids', '');

        if (!$chatUserIds) {
            return $this->setError(ErrorCode::PARAMETER_ERROR);
        }

        $profile = $this->getUserInfo($this->actionUserId);
        if (!$profile || $profile->gender != 0) {
            return $this->setError(0, '用户不存在或无操作权限');
        }

        $chatUserIds = explode(',', $chatUserIds);

        $this->getRedis();

        //判断缓存
        if (!$this->checkCacheCondition()) {
            return $this->setError(self::ERROR_CODE, '搭讪较快，休息' . AccostBusinesswomen::LOCK_TIME . '分钟后再试吧～');
        }


        $haveRecommended = $this->getUserRecommendData();

        //排除已经打过的招呼
        foreach ($chatUserIds as $oneUserId) {
            if (!check_dev_env() && in_array($oneUserId, $haveRecommended)) {
                $chatUserIds = array_diff($chatUserIds, [$oneUserId]);
            }
        }

        //获取自动招呼消息
        if (!$isNewVersion) {
            $autoMsg = UserAutoMsg::pickUserMsg($this->actionUserId);
            $issetAutoMsg = isset($autoMsg['is_default']) && $autoMsg['is_default'] == 0;
            $ret['auto_msgs'] = [$autoMsg];
            $versionFlag = 1;
        } else {
            //新版
            $ret['auto_msgs'] = UserAutoMsg::pickQuickChatMsgs($this->actionUserId);
            $issetAutoMsg = !empty($ret['auto_msgs']);
            $versionFlag = 2;
        }

        //声优的自动回复没有设置
        if (!$issetAutoMsg) {
            return $this->setError(ErrorCode::NO_AUTO_MSG, '没有设置自动发送消息');
        }

        //批量发送私信
        $imAccounts = User::getImAccounts($chatUserIds);
        $ret['list'] = array_values(array_unique($imAccounts));
        if (count($ret['list']) != count($chatUserIds)) {
            log_info('batchAccostError:' . __CLASS__ . '发送上来并且排除的值:' . json_encode($chatUserIds) . "==查询出来的数量:{" . count($ret['list']) . "}:查询出来的值:" . json_encode($ret['list']));
        }

        if (empty($chatUserIds)) {
            return $this->setError(self::ERROR_CODE, '请不要重复搭讪');
        }

        $command = $this->addData($chatUserIds);
        if (!$command) {
            return $this->setError(self::ERROR_CODE, '搭讪失败');
        }

        $accostLogModel = new AccostLog();

        $accostLogModel->user_id = $this->actionUserId;
        $accostLogModel->token_data = $this->request->getHeader('Authorization')[0] ?? '';
        $accostLogModel->data = json_encode($ret['auto_msgs']);
        $accostLogModel->version_flag = $versionFlag;
        $accostLogModel->request_data = json_encode($this->request->all());
        $accostLogModel->to_user_ids = json_encode($chatUserIds);
        $accostLogModel->save();

        return $ret;
    }

    /**
     * 添加数据
     * @param $userIds
     * @return bool
     * @throws RedisException
     */
    private function addData($userIds): bool
    {
        $insertData = [];
        foreach ($userIds as $one) {
            $insertData[] = [
                'user_id' => $this->actionUserId,
                'chat_user_id' => $one,
                'flag' => 1,
                'from' => UserChat::FROM_QUICK_CHAT
            ];
        }
        $insert = Db::table('user_chat')->insert($insertData);
        if (!$insert) {
            return false;
        }

        $this->redis->sAddArray($this->key, $userIds);

        $script1 = <<<lua
            local numStr = redis.call('exists',KEYS[1])
            if numStr == 1 then
                redis.call('incrBy',KEYS[1],ARGV[1])
            else
                redis.call('incrBy',KEYS[1],ARGV[1])
                redis.call('Expire',KEYS[1],ARGV[2])
            end

            local totalNum = tonumber(redis.call('get',KEYS[1]))
            if totalNum >= tonumber(ARGV[3]) then
                redis.call('set',KEYS[2],"1")
                redis.call('Expire',KEYS[2],ARGV[4])
            end
        lua;

        //执行数量和是否锁定逻辑
        $this->redis->eval($script1, [
            $this->numKey,//搭讪数量的key
            $this->lockKey,//锁定的key
            count($userIds),//这次搭讪有多少人
            AccostBusinesswomen::CONDITION_TIME * 60,//搭讪数量的key的时间(分钟)
            AccostBusinesswomen::CONDITION_NUMBER,//搭讪数量的最大值（达到这个值锁定）
            AccostBusinesswomen::LOCK_TIME * 60//搭讪锁定的时间(分钟)
        ], 2);

        return true;
    }


}
